﻿#include "mcustomplot.h"
static const QColor colors[] =
    {
        Qt::red,
        Qt::green,
        Qt::blue,
        Qt::cyan,
        Qt::magenta,
        Qt::gray,
        Qt::darkRed,
        Qt::darkGreen,
        Qt::darkBlue,
        Qt::darkCyan,
};
Mcustomplot::Mcustomplot(QWidget* parent):
    QCustomPlot(parent){
    initPlot();
    SlotItemChange("1",true);
    SlotItemChange("2",true);
    UpdateSettingCommonXaXisx();
    // for (int var = 0; var < 100; ++var) {
    //     SlotDataTimeOut();
    // }
}
/**
 * @brief Mcustomplot::CreateQCPAxisRect 、动态增加channel所对应的坐标系
 * @param channel
 * @return
 */
QCPAxisRect* Mcustomplot::CreateQCPAxisRect(QString channel)
{
    //channel代表坐标系id
    QCPAxisRect* axisRect = new QCPAxisRect(this, true);
    axisRect->setupFullAxesBox(true);
    axisRect->setRangeZoom(Qt::Horizontal | Qt::Vertical);
    QCPAxis* poAxisX = axisRect->axis(QCPAxis::atBottom);	//x轴
    QCPAxis* poAxisY = axisRect->axis(QCPAxis::atLeft);		//y轴
    poAxisX->setRange(0, 20);
    poAxisY->setRange(0, 50);
    axisRect->axis(QCPAxis::atTop)->setVisible(false);
    axisRect->axis(QCPAxis::atRight)->setVisible(false);
    poAxisX->grid()->setSubGridVisible(true);
    poAxisY->grid()->setSubGridVisible(true);
    axisRect->setAutoMargins(QCP::msRight | QCP::msLeft);
    axisRect->setMargins(QMargins(100, 0, 0, 0));
    poAxisY->setPadding(5); // 这里的5是你想要的额外填充
    poAxisY->setTickLabelPadding(10); // 这里的5是你想要的额外填充
    poAxisY->setLabelPadding(10); // 这里的5是你想要的额外填充
    poAxisX->setVisible(true);
    poAxisX->setLabel("时间(s)");
    poAxisY->rescale(true);			//y轴自适应
    //设置x轴y轴自由缩放
    QList<QCPAxis*> aaxisField;
    aaxisField << poAxisX;
    aaxisField << poAxisY;
    axisRect->setRangeZoomAxes(aaxisField);

    poAxisY->setVisible(true);
    poAxisY->setLabel("通道" + channel);
    auto poGraph = this->addGraph(poAxisX, poAxisY);
    QPen pen;
    pen.setColor(colors[m_channel_plots.count() % 10]);
    poGraph->setPen(pen);

    //下面这两行使得Y轴轴线总是对齐
    axisRect->setAutoMargins(QCP::MarginSide::msLeft | QCP::MarginSide::msRight);
    m_channel_axises.insert(channel.toInt(), axisRect);
    m_channel_plots.insert(channel.toInt(), poGraph);
    return axisRect;
}
/**
 * @brief Mcustomplot::RemoveQCPAxisRect 动态删除channel所对应的坐标系
 * @param channel
 */
void Mcustomplot::RemoveQCPAxisRect(QString channel)
{
    if (m_channel_axises.contains(channel.toInt()) && m_channel_plots.contains(channel.toInt()))
    {
        auto axes_rect = m_channel_axises.value(channel.toInt());
        auto graph_plot = m_channel_plots.value(channel.toInt());
        this->plotLayout()->remove(axes_rect);
        this->plotLayout()->simplify();
        m_channel_axises.remove(channel.toInt());
        m_channel_plots.remove(channel.toInt());
    }
}
/**
 * @brief Mcustomplot::UpdateSettingCommonXaXisx 多段y轴共用同一个x轴
 */
void Mcustomplot::UpdateSettingCommonXaXisx()
{
    auto elements = this->plotLayout()->elementCount();
    for (int row = 0; row < elements; row++)
    {
        QCPAxisRect* poRecti = (QCPAxisRect*)this->plotLayout()->element(row, 0);
        if (poRecti)
        {
            //布局中最后一个元素进行设置
            if (row == (elements - 1))
            {
                poRecti->setMargins(QMargins(100, 0, 0, 40));
                poRecti->axis(QCPAxis::atBottom)->setVisible(true);
            }
            else
            {
                poRecti->setMargins(QMargins(100, 0, 0, 0));
                poRecti->axis(QCPAxis::atBottom)->setVisible(false);
            }
        }
    }
}
/**
 * @brief Mcustomplot::ConnectAllAxisx 当鼠标放大缩小上下移动时 ，多段y轴x轴同步
 * @param on
 */
void Mcustomplot::ConnectAllAxisx(bool on)
{
    auto elements = this->plotLayout()->elementCount();
    for (int i = 0; i < elements; i++)
    {
        QCPAxisRect* poRecti = (QCPAxisRect*)this->plotLayout()->element(i, 0);
        for (int j = 0; j < elements; j++)
        {
            QCPAxisRect* poRectj = (QCPAxisRect*)this->plotLayout()->element(j, 0);
            if (poRectj && poRecti && i!=j)
            {
                connect(poRecti->axis(QCPAxis::atBottom), QOverload<const QCPRange&>::of(&QCPAxis::rangeChanged),
                        poRectj->axis(QCPAxis::atBottom), QOverload<const QCPRange&>::of(&QCPAxis::setRange));
                connect(poRecti->axis(QCPAxis::atLeft), QOverload<const QCPRange&>::of(&QCPAxis::rangeChanged),
                        poRectj->axis(QCPAxis::atLeft), QOverload<const QCPRange&>::of(&QCPAxis::setRange));
            }
        }
    }
}
void Mcustomplot::initPlot()
{

    plotLayout()->clear();
//允许用户用鼠标拖动轴范围，以鼠标为中心滚轮缩放，点击选择图形:
    setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);
}
void Mcustomplot::SlotItemChange(QString id, bool check)
{
    if (check)
    {
        auto rows = this->plotLayout()->rowCount();
        QCPAxisRect* axisRect = CreateQCPAxisRect(id);
        this->plotLayout()->addElement(rows++, 0, axisRect);
        UpdateSettingCommonXaXisx();
        ConnectAllAxisx(true);
    }
    else
    {
        //移除该通道坐标及曲线
        RemoveQCPAxisRect(id);
        UpdateSettingCommonXaXisx();
        max = 50;
        min = 0;
    }
    this->replot();
}
void Mcustomplot::SlotDataTimeOut()
{
    QCPAxis* poAxisY = NULL;
    static double key = 0;; // 开始到现在的时间，单位
    for (auto& pair : m_channel_plots.toStdMap())
    {
        int value = (QRandomGenerator::global()->bounded(101) % 10 )* (QRandomGenerator::global()->bounded(101) % 10);
        auto channel = pair.first;
        auto graph = pair.second;
        graph->addData(key,value);
        if (m_channel_axises.contains(channel))
        {
            auto AxisRec = m_channel_axises.value(channel);
            QCPAxis* poAxisY = AxisRec->axis(QCPAxis::atLeft);		//y轴
            poAxisY->rescale(true);
            int upper = (int)(poAxisY->range().upper);
            int lower = (int)(poAxisY->range().lower);

            if (value > max)
            {
                max = value+20;
                //poAxisY->setRangeUpper(value + 50);
            }
            else if (value < min)
            {
                min = value-20;
                //poAxisY->setRangeLower(value - 50);
            }

            if (key > 2000)
                AxisRec->axis(QCPAxis::atBottom)->setRange(key, 2000, Qt::AlignRight);
        }
    }
    if (poAxisY && (max!=0))
    {
        poAxisY->setRangeUpper(max);
        poAxisY->setRangeLower(min);
    }
    key+=0.5;
    //绘图
    this->replot();
}

void Mcustomplot::addPlotData(const int index, const double x, const double y)
{
    m_channel_plots.value(index)->addData(x,y);

        auto AxisRec = m_channel_axises.value(index);
        QCPAxis* poAxisY = AxisRec->axis(QCPAxis::atLeft);		//y轴
        poAxisY->rescale(true);
        int upper = (int)(poAxisY->range().upper);
        int lower = (int)(poAxisY->range().lower);

        if (y > max)
        {
            max = y+20;
            //poAxisY->setRangeUpper(value + 50);
        }
        else if (y < min)
        {
            min = y-20;
            //poAxisY->setRangeLower(value - 50);
        }

        if (x > 2000)
            AxisRec->axis(QCPAxis::atBottom)->setRange(x, 2000, Qt::AlignRight);

    if (poAxisY && (max!=0))
    {
        poAxisY->setRangeUpper(max);
        poAxisY->setRangeLower(min);
    }
    this->replot();
}
